/*********************************************************************\
*
*                  (c) lkc
*                  All Rights Reserved. lkc Confidential
*
\*********************************************************************/
/*********************************************************************\
*   Title                      :
*
*   Module Description         :
*
*   Author                     : lkc
*
*   Created                    : 2018-7-24
*
\*********************************************************************/

#include <sys/epoll.h>
#include <thread>
#include "EpollFunc.h"
#include "Communicate.h"

int commEpollFd = epoll_create(5); //int epoll_create(int size); 自从linux2.6.8之后，size参数是被忽略的。

void EpollHandleThread(int fd)//处理一个epoll触发的事件
{
    while(true)
    {
        int ret = protocolMap[fd]->GetCommTool()->ReadAndParse();
        if( ret == 0 )
        {
//            close( fd );
            printf( "foreiner closed the connection\n" );
            break;
        }
        else if( ret < 0 )
        {
            if( errno == EAGAIN )
            {
                EpollSetOneshot( commEpollFd, fd );
//                printf( "read later\n" );
                break;
            }
        }
    }
//    printf( "end thread receiving data on fd: %d\n", fd );
}

void EpollThread()
{
    int MAX_EVENT_NUMBER  = 1024;
    epoll_event events[MAX_EVENT_NUMBER];
    while(true)
    {
        int ret = epoll_wait( commEpollFd, events, MAX_EVENT_NUMBER, -1 );
        if ( ret < 0 )
        {
            printf( "epoll failure\n" );
            break;
        }
        for ( int i = 0; i < ret; i++ )
        {
            epoll_event evt = events[i];
            if ( evt.events & EPOLLIN )
            {
                std::thread(EpollHandleThread,evt.data.fd).detach();
            }
            else
            {
                printf( "something else happened \n" );
            }
        }
    }
}

bool CommEpollManageInit()
{
    if(protocolMap.size()<1)
    {
        printf("protocolMap.size()<1\n");
        return true;
    }
    if(commEpollFd==-1)
    {
        printf("epoll_create error");
        return false;
    }
    for(auto &value : protocolMap)
    {
        int fd = value.second->GetFd();
        if(fd<0)
        {
            printf("fd<0\n");
            continue;
        }
        EpollAddFd(commEpollFd,fd,true);
    }

    std::thread(EpollThread).detach();
    return true;
}

/********************************************************************\
 *
 * REVISION RECORDS
 *
\*********************************************************************/
/*********************************************************************/
/*
 *
 *
 *
\*********************************************************************/
/*------------------------------The End------------------------------*/


